package com.study.sbsummary.utils;

import com.truely.plog.serving.config.database.shadow.ShadowConstants;
import com.truely.plog.serving.context.RequestContext;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class URLUtil {
    public static final String UTF_8 = StandardCharsets.UTF_8.name();
    public static URLInfo parseUrl(String url) throws Exception {
        return new URLInfo(url);
    }

    public static String checkAndSetOnlineTest(String url) {
        if (RequestContext.isOnlineTest()) {
            int lastUrl = url.lastIndexOf('?');
            if (lastUrl > 0) {
                if (lastUrl < url.length() - 1) {
                    url += "&" + ShadowConstants.PRESSURE_TEST_PARAM_AND_VALUE;
                } else {
                    url += ShadowConstants.PRESSURE_TEST_PARAM_AND_VALUE;
                }
            } else {
                url += "?" + ShadowConstants.PRESSURE_TEST_PARAM_AND_VALUE;
            }
        }
        return url;
    }

    public static String combineQueryParams(String url, Map<String, String> params) {
        StringBuilder sb = new StringBuilder();
        sb.append(url);
        sb.append("?");
        for (Map.Entry entry : params.entrySet()) {
            sb.append(entry.getKey());
            sb.append("=");
            sb.append(entry.getValue());
            sb.append("&");
        }
        sb.deleteCharAt(sb.lastIndexOf("&"));
        return sb.toString();
    }

    @Data
    public static class URLInfo {
        private String url;
        private URL internalURL;
        private UserInfo userInfo;

        Map<String, String> params = new HashMap<>();
        public URLInfo(String url) throws Exception {
            this.url = url;
            this.internalURL = new URL(URLDecoder.decode(url, UTF_8));
            if (StringUtils.isNotEmpty(internalURL.getUserInfo())) {
                String[] us = internalURL.getUserInfo().split(":");
                UserInfo userInfo = new UserInfo();
                userInfo.setUser(us[0]);
                if (us.length > 1) {
                    userInfo.setPassword(us[1]);
                }
            }
            if (StringUtils.isNotEmpty(internalURL.getQuery())) {
                String[] p = internalURL.getQuery().split("&");
                for (String query : p) {
                    String[] param = query.split("=");
                    if (param.length > 1) {
                        params.put(param[0], param[1]);
                    } else {
                        params.put(param[0], "");
                    }
                }
            }
        }

        public String schema() {
            return this.internalURL.getProtocol();
        }

        public String hostname() {
            return this.internalURL.getHost();
        }

        public int port() {
            if (this.internalURL.getPort() > 0) {
                return internalURL.getPort();
            }
            return this.internalURL.getDefaultPort();
        }

        public String query() {
            return this.internalURL.getQuery();
        }

        public Map params() {
            return this.params;
        }

        public String user() {
            if (userInfo != null) {
                return userInfo.getUser();
            }
            return null;
        }

        public String password() {
            if (userInfo != null) {
                return userInfo.getPassword();
            }
            return null;
        }

        public String path() {
            return internalURL.getPath();
        }

        @Data
        public static class UserInfo {
            private String user;
            private String password;
        }
    }
}
